﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace GraphicsEditor
{
    public partial class ToolboxUserControl : UserControl
    {
        // preview measuremement variables

        private Size previewShapeSize;
        private Point previewShapeLocation;
        private Rectangle previewShapeBounds;

        private Size previewEraserSize;
        private Point previewEraserLocation;
        private Rectangle previewEraserBounds;

        private Point[] previewPolygonPoints;

        public ToolboxUserControl()
        {
            InitializeComponent();
            InitializeComboBox();
            InitializePreviewShapeMeasurements();
            scribbleButton_Click(scribbleButton, new EventArgs());
        }

        /// <summary>
        /// Update all control status according to one child.
        /// </summary>
        /// <param name="child"></param>
        private void UpdateToolbox(ScrollableCanvasForm child)
        {
            if (child == null)
                return;
            RadioButton[] tools = new RadioButton[] { selectButton, rectangleButton, ellipseButton, polygonButton, lineButton, eraseButton, scribbleButton };
            tools[(int)child.Mode].Checked = true;
            outlineColorButton.BackColor = child.Pen.Color;
            outlineAlphaNumericUpDown.Value = child.Pen.Color.A;
            fillColorButton.BackColor = child.Brush.ForeColor;
            fillAlphaNumericUpDown.Value = child.Brush.ForeColor.A;
            outlineColorButton.BackColor = child.Pen.Color;
            fillColorButton.BackColor = child.Brush.ForeColor;


            previewPanel.Refresh();
        }

        private void EnableTools(GraphicsEditor.DrawMode mode)
        {

            eraserGroupBox.Enabled = false;
            outlineGroupBox.Enabled = false;
            fillGroupBox.Enabled = false;

            //Enabled controls
            switch (mode)
            {
                case GraphicsEditor.DrawMode.Erase:
                    eraserGroupBox.Enabled = true;
                    break;

                case GraphicsEditor.DrawMode.Line:
                case GraphicsEditor.DrawMode.Scribble:
                    outlineGroupBox.Enabled = true;
                    break;

                case GraphicsEditor.DrawMode.Rectangle:
                case GraphicsEditor.DrawMode.Ellipse:
                case GraphicsEditor.DrawMode.Polygon:
                    outlineGroupBox.Enabled = true;
                    fillGroupBox.Enabled = true;
                    break;
            }
        }

        /// <summary>
        /// Get the current active child window from parent.
        /// </summary>
        /// <returns></returns>
        private ScrollableCanvasForm GetActiveChild()
        {
            if (Parent == null)
                return null;
            if ((Parent as GraphicsEditorForm).ActiveMdiChild == null)
                return null;
            return (Parent as GraphicsEditorForm).ActiveMdiChild as ScrollableCanvasForm;
        }

        /// <summary>
        /// When active child changed, update the controls according to the current child.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ActiveChildChanged(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child != null)
            {
                EnableTools(child.Mode);
                UpdateToolbox(child);
            }
        }


        private void InitializeComboBox()
        {
            previewViewComboBox.DataSource = Enum.GetValues(typeof(GraphicsEditor.PreviewView));
        }


        private void InitializePreviewShapeMeasurements()
        {
            previewShapeSize = new Size(previewPanel.Width / 2, previewPanel.Height / 2);
            previewShapeLocation = new Point((previewPanel.Width - previewShapeSize.Width) / 2, (previewPanel.Height - previewShapeSize.Height) / 2);
            previewShapeBounds = new Rectangle(previewShapeLocation, previewShapeSize);

            previewPolygonPoints = new Point[5];
            previewPolygonPoints[0] = new Point(previewShapeLocation.X + (previewShapeSize.Width / 2), previewShapeLocation.Y);
            previewPolygonPoints[1] = new Point(previewShapeLocation.X + previewShapeSize.Width, previewShapeLocation.Y + (previewShapeSize.Height / 3));
            previewPolygonPoints[2] = new Point(previewShapeLocation.X + previewShapeSize.Width - (previewShapeSize.Width / 5), previewShapeLocation.Y + previewShapeSize.Height);
            previewPolygonPoints[3] = new Point(previewShapeLocation.X + (previewShapeSize.Width / 5), previewShapeLocation.Y + previewShapeSize.Height);
            previewPolygonPoints[4] = new Point(previewShapeLocation.X, previewShapeLocation.Y + (previewShapeSize.Height / 3));
        }

        //public void ToolboxForm_Load()
        //{
        //    scribbleButton.PerformClick();
        //}

        private void eraseButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child != null)
            {
                child.Mode = GraphicsEditor.DrawMode.Erase;
                previewPanel.Refresh();
            }
        }

        private void scribbleButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child != null)
            {
                child.Mode = GraphicsEditor.DrawMode.Scribble;
                EnableTools(child.Mode);
                previewPanel.Refresh();
            }
        }

        private void lineButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child != null)
            {
                child.Mode = GraphicsEditor.DrawMode.Line;
                EnableTools(child.Mode);
                previewPanel.Refresh();
            }
        }

        private void rectangleButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child != null)
            {
                child.Mode = GraphicsEditor.DrawMode.Rectangle;
                EnableTools(child.Mode);
                previewPanel.Refresh();
            }
        }

        private void ellipseButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child != null)
            {
                child.Mode = GraphicsEditor.DrawMode.Ellipse;
                EnableTools(child.Mode);
                previewPanel.Refresh();
            }
        }

        private void polygonButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child != null)
            {
                child.Mode = GraphicsEditor.DrawMode.Polygon;
                EnableTools(child.Mode);
                previewPanel.Refresh();
            }
        }

        private void selectButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child != null)
            {
                child.Mode = GraphicsEditor.DrawMode.Select;
                EnableTools(child.Mode);
                previewPanel.Refresh();
            }
        }

        private void previewViewComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            GraphicsEditor.PreviewView previewView = (GraphicsEditor.PreviewView)previewViewComboBox.SelectedValue;
            switch (previewView)
            {
                case GraphicsEditor.PreviewView.Canvas:
                    previewPanel.BackgroundImage = null;
                    previewPanel.BackColor = GraphicsEditor.CANVAS_COLOR;
                    break;
                case GraphicsEditor.PreviewView.Checkerboard:
                    previewPanel.BackgroundImage = Properties.Resources.checkerboard;
                    break;
            }
        }

        private void previewPanel_Paint(object sender, PaintEventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child == null)
                return;

            switch (child.Mode)
            {
                case GraphicsEditor.DrawMode.Erase:
                    UpdatePreviewEraserMeasurements();
                    e.Graphics.FillRectangle(new SolidBrush(GraphicsEditor.ERASER_FILL_COLOR), previewEraserBounds);
                    e.Graphics.DrawRectangle(new Pen(new SolidBrush(GraphicsEditor.ERASER_OUTLINE_COLOR)), previewEraserBounds);
                    break;
                case GraphicsEditor.DrawMode.Line:
                    e.Graphics.DrawLine(child.Pen.GetPen(), previewShapeLocation, new Point(previewShapeLocation.X + previewShapeSize.Width, previewShapeLocation.Y + previewShapeSize.Height));
                    break;
                case GraphicsEditor.DrawMode.Rectangle:
                    e.Graphics.FillRectangle(child.Brush.GetBrush(), previewShapeBounds);
                    e.Graphics.DrawRectangle(child.Pen.GetPen(), previewShapeBounds);
                    break;
                case GraphicsEditor.DrawMode.Ellipse:
                    e.Graphics.FillEllipse(child.Brush.GetBrush(), previewShapeBounds);
                    e.Graphics.DrawEllipse(child.Pen.GetPen(), previewShapeBounds);
                    break;
                case GraphicsEditor.DrawMode.Polygon:
                    e.Graphics.FillPolygon(child.Brush.GetBrush(), previewPolygonPoints);
                    e.Graphics.DrawPolygon(child.Pen.GetPen(), previewPolygonPoints);
                    break;
                case GraphicsEditor.DrawMode.Scribble:
                    e.Graphics.DrawArc(child.Pen.GetPen(), new Rectangle(previewShapeLocation, new Size(previewShapeSize.Width / 2, previewShapeSize.Height)), 180, 180);
                    e.Graphics.DrawArc(child.Pen.GetPen(), new Rectangle(new Point(previewShapeLocation.X + (previewShapeSize.Width / 2), previewShapeLocation.Y), new Size(previewShapeSize.Width / 2, previewShapeSize.Height)), 0, 180);
                    break;
            }
        }

        private void UpdatePreviewEraserMeasurements()
        {
            int side = (int)eraserSizeNumericUpDown.Value;

            previewEraserSize = new Size(side, side);
            previewEraserLocation = new Point((previewPanel.Width - previewEraserSize.Width) / 2, (previewPanel.Height - previewEraserSize.Height) / 2);
            previewEraserBounds = new Rectangle(previewEraserLocation, previewEraserSize);
        }

        private void ControlSettingsChanged(object sender, EventArgs e)
        {
            previewPanel.Refresh();
        }

        private void outlineColorButton_Click(object sender, EventArgs e)
        {

            ScrollableCanvasForm child = GetActiveChild();
            if (child == null)
                return;
            ColorDialog colorDialog = new ColorDialog();
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                child.Pen.Color = Color.FromArgb(child.Pen.Color.A, colorDialog.Color);
                outlineColorButton.BackColor = child.Pen.Color;
                previewPanel.Refresh();
            }

        }

        private void fillColorButton_Click(object sender, EventArgs e)
        {

            ScrollableCanvasForm child = GetActiveChild();
            if (child == null)
                return;
            ColorDialog colorDialog = new ColorDialog();
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                child.Brush.ForeColor = Color.FromArgb(child.Pen.Color.A, colorDialog.Color);
                fillColorButton.BackColor = child.Brush.ForeColor;
                previewPanel.Refresh();

            }

        }

        private void outlineAdvancedSettingsButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child == null)
                return;

            PenDialog penDialog = new PenDialog(child.Pen);
            if (penDialog.ShowDialog() == DialogResult.OK)
            {
                if (child != null)
                {
                    child.Pen = penDialog.Pen;
                    outlineColorButton.BackColor = child.Pen.Color;
                    previewPanel.Refresh();
                }
            }
        }

        private void fillAdvancedSettingsButton_Click(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child == null)
                return;
            BrushDialog brushDialog = new BrushDialog(child.Brush);

            if (brushDialog.ShowDialog() == DialogResult.OK)
            {
                child.Brush = brushDialog.Brush;
                fillColorButton.BackColor = child.Brush.ForeColor;
                previewPanel.Refresh();
            }
        }

        private void outlineAlphaNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child == null)
                return;
            child.Pen.Color = Color.FromArgb((int)outlineAlphaNumericUpDown.Value, child.Pen.Color);
            outlineColorButton.BackColor = child.Pen.Color;
            previewPanel.Refresh();

        }



        private void fillAlphaNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            ScrollableCanvasForm child = GetActiveChild();
            if (child == null)
                return;
            child.Brush.ForeColor = Color.FromArgb((int)fillAlphaNumericUpDown.Value, child.Brush.ForeColor);
            fillColorButton.BackColor = child.Brush.ForeColor;
            previewPanel.Refresh();
        }

    }
}
